﻿/*
 * SpatialDbCommand
 * 
 * initial implementation : 20.9.2008
 *
 * Copyright (c) Adam Sida, asida@centrum.cz.
 * All rights reserved.
 * 
 * for license see Petra.Gis.License.txt
 */
using System;
using System.Text.RegularExpressions;
//using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Windows.Markup;
//using Petra.Gis.Geometry.Support;
//using Petra.Gis.DataServices.Metadata;
using Petra.Gis.ReferenceSystemServices;



namespace Petra.Gis.DataServices
{
  public abstract partial class SpatialDbCommand : DbCommand
  {


    /// <summary>
    /// this is defensive coordinate system search method, prepared for databases
    /// that knows nothing about coordinate systems or have closed proprietary
    /// cs format. Method first tries to parse cs by xaml (user might have extra string type
    /// field within database) and if this failes, tries search
    /// by authority and code in Petra.Gis.ReferenceSystems
    /// coordinate system database
    /// </summary>
    /// <param name="csInfo"></param>
    /// <returns></returns>
    protected CoordinateSystem parseCoordinateSystemInfo(string csInfo)
    {

      CoordinateSystem result = null;

      // try first xaml and parse as Petra.Gis.ReferenceServices.CoordinateSystem
      try
      {
        result = (CoordinateSystem)XamlReader.Parse(csInfo);
        return result;
      }
      catch { }

      // ok, not xaml, must have string with:
      // Authority and Code that is compared to Petra.Gis.ReferenceSystems system database

      Match m;
      string rPattern;

      //rPattern = @"(((?<authorityLabel>Authority)\s*\=\s*(?<authority>\w+)\s*" +
      //                  @"(?<codeLabel>Code)\s*\=\s*(?<code>\w+))|" +
      //                  @"((?<authority>EPSG)\:(?<code>\w+)))\s*(StorageUnits\s*\=\s*(?<storegeUnitName>\w+))";

      rPattern = @"((?<authority>EPSG)\:(?<code>\w+))";
      m = new Regex(rPattern).Match(csInfo);

      if (m.Length == 0)
      {
        rPattern = @"((?<authorityLabel>Authority)\s*\=\s*(?<authority>\w+)\s*\;?\s*" +
                   @"(?<codeLabel>Code)\s*\=\s*(?<code>\w+))";
        m = new Regex(rPattern).Match(csInfo);

        if(m.Length == 0)
          throw new ArgumentException(@"canot parse coordinate system Authority=xxx 
                                        and Code=xxx from csInfo:" + csInfo);
      }

      string authority = m.Groups["authority"].Captures[0].Value;
      string code = m.Groups["code"].Captures[0].Value;

      // parse storageUnit name
      rPattern = @"(StorageUnits\s*\=\s*(?<storegeUnitName>\w+))";
      m = new Regex(rPattern).Match(csInfo);

      if (m.Length == 0)
        throw new ArgumentException("canot parse coordinate system storage units from csInfo:" + csInfo);

      string storageUnitName = m.Groups["storegeUnitName"].Captures[0].Value;

      //result = ReferenceSystemServices.CoordinateSystem.SearchBy(authority, code, storageUnitName);
      result = Petra.Gis.SystemEnvironment.SRSLibrary.SearchBy(authority, code, storageUnitName);


      if (result == null)
        throw new ArgumentException("coordinate system specified by Authority= " + authority +
                                     ", Code= " + code + " and  StorageUnits= " + storageUnitName + " not found" +
                                     " in ReferenceSystemServices.SearchCoordinateSystem database" +
                                     " please update your system database first or change" +
                                     " coordinate system definition in your database (vendor specific task)");


      return result;
    }


  }
}
